package org.jeecg.modules.front.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wechat.pay.java.core.exception.ValidationException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.front.entity.vo.PayOrder;
import org.jeecg.modules.front.pay.Payment;
import org.jeecg.modules.front.pay.PaymentFactory;
import org.jeecg.modules.front.util.*;
import org.jeecg.modules.gongqiang.entity.*;
import org.jeecg.modules.gongqiang.service.*;
import org.jeecg.modules.yinsheng.utils.YsChannelClientException;
import org.jeecg.modules.yinsheng.utils.YsMpPayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author scott
 * @since 2018-12-17
 */
@RestController
@RequestMapping("/front/yinsheng")
@Api(tags = "前台用户基础模块")
@Slf4j
public class FrontOrderYinShengController {
    @Autowired
    private IGoodTypeService goodTypeService;
    @Autowired
    private IGoodService goodService;
    @Autowired
    private IUserhomeOrderService userhomeOrderService;
    @Autowired
    private IGoodDetailService goodDetailService;
    @Autowired
    private ISerialNumberService serialNumberService;

    @Autowired
    private IUserhomeService userhomeService;

    @Autowired
    private RestTemplate restTemplate;



    @ApiOperation("订单银盛聚合支付")
    @RequestMapping(value = "/yinsheng/pay", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public Result<JSONObject> wxPayOrder(@RequestBody PayOrder payOrder, HttpServletRequest req) throws InstantiationException, IllegalAccessException {
        UserhomeOrder userhomeOrder = userhomeOrderService.getByIdLock(payOrder.getOrderId());
        if (userhomeOrder == null) {
            return Result.error("订单不存在!");
        }
        if (!userhomeOrder.getStatus().equals(0)) {
            return Result.error("订单已不可支付!");
        }
        Good good = goodService.getById(userhomeOrder.getGoodId());
        if (good == null) {
            return Result.error("商品已下架!");
        }

        Map<String, String> extendParams = new HashMap<>();
        if(payOrder.getPlatform().equals("Yinsheng")&&payOrder.getWay().equals("scan")&&payOrder.getChannel().equals("wechat"))
        {
            Integer userId = JwtUtil.getUserId(req.getHeader("X-Access-Token"));
            Userhome userhome = userhomeService.getById(userId);
            if (oConvertUtils.isEmpty(userhome.getWoaopenid())) {
                return Result.error("没有获取openid");
            }
            extendParams.put("wxOpenId", userhome.getWoaopenid());
        }
        extendParams.put("name", good.getName());
        extendParams.put("num", String.valueOf(userhomeOrder.getNum()));
        PaymentFactory factory = new PaymentFactory();
        Payment payment = factory.createPayment(payOrder.getPlatform(), payOrder.getWay(), payOrder.getChannel());
        try {
            //更新支付类型
            userhomeOrder.setPayType(payment.payType());
            userhomeOrderService.updateById(userhomeOrder);
            //拉起支付
            return payment.pay(userhomeOrder.getOrderNum(), userhomeOrder.getTprice(), extendParams);
        } catch (Exception e) {
            log.warn(e.getMessage());
            return Result.error(e.getMessage());
        }

    }

    @RequestMapping(value = "/yinsheng/notify", method = {RequestMethod.GET, RequestMethod.POST})
    @Transactional(rollbackFor = Exception.class)
    public String yinshengNotify(HttpServletRequest req) throws YsChannelClientException {
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        Map<String, String[]> requestParams = req.getParameterMap();
        String sign = null;
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }
        //验证签名
        String result = map.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining(", "));
        log.info("银盛渠道异步返回[" + result + "]");
        try {
            if (!YsMpPayUtils.verifySign(YinShengUtil.getPubKeyPath(), map, false)) {
                return "error";
            }
            JSONObject jsonObject = JSONObject.parseObject(map.get("bizResponseJson"));
            if (jsonObject.getString("state").equals("SUCCESS")) {
                //处理业务逻辑
                String outTradeNo = jsonObject.getString("requestNo");
                String totalAmount = jsonObject.getString("amount");
                LambdaQueryWrapper<UserhomeOrder> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(UserhomeOrder::getOrderNum, outTradeNo);
                UserhomeOrder userhomeOrder = userhomeOrderService.getOne(queryWrapper);
                String tprice = String.format("%.2f", userhomeOrder.getTprice());
                if (!tprice.equals(totalAmount)) {
                    return "error";
                }
                userhomeOrderService.payStatus(1, outTradeNo);
                Map<String, Object> params=new HashMap<>();
                params.put("merchantNo", YinShengUtil.getPrdPayeeMerchantNo());
                params.put("type", 2);
                params.put("out_trade_no", outTradeNo);
                params.put("money", totalAmount);
                YinShengUtil.report(params);
                return "success";
            }
        } catch (ValidationException e) {
            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
        }
        return "error";
    }


    @ApiOperation(value = "获取openid", notes = "获取openid")
    @GetMapping(value = "/openid")
    public Result<?> openid(GoodType goodType,
                            @RequestParam(name = "code", required = true) String code,
                            @RequestParam(name = "state", required = true) String state,
                             HttpServletRequest req
                            ) {
        String appId= YinShengUtil.getWAppID();
        String appSecret= YinShengUtil.getWAppSecret();
        // 换取 Access Token 和 OpenID
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appId+"&secret="+appSecret+"&code="+code+"&grant_type=authorization_code";
        String jsonString  = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSON.parseObject(jsonString);
        String openid = jsonObject.getString("openid");
        if (oConvertUtils.isEmpty(openid)) {
            return Result.error("获取不到openid");
        }
       // 获取用户的 OpenID
       // 存入数据库用户的 OpenID
       Userhome userhome = userhomeService.getById(state);
        userhome.setWoaopenid(openid);
        userhomeService.updateById(userhome);
        return Result.OK("成功");
    }
}